package com.qf.hospital.system.controller;

import com.github.pagehelper.PageInfo;
import com.qf.hospital.system.dto.SysRoleDTO;
import com.qf.hospital.system.entity.SysRole;
import com.qf.hospital.system.entity.SysUser;
import com.qf.hospital.system.enums.HospitalEnum;
import com.qf.hospital.system.service.SysUserService;
import com.qf.hospital.system.util.R;
import com.qf.hospital.system.vo.ResultVO;
import com.qf.hospital.system.vo.SideTreeVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * 系统用户
 */
@RestController
@Slf4j
public class SysUserController {

    @Autowired
    private SysUserService sysUserService;

    /**
     * 登录功能
     * # 请求路径和方式
     *   Request URL: http://localhost:8080/sel/doLogin
     *   Request Method: POST
     * # 请求参数
     *   loginname: admin
     *   pwd: admin
     * # 响应数据
     *   SUCCESS:
     *   {
     *       "code": 0
     *       "msg": "登录成功!"
     *   }
     *   FAIL:
     *   {
     *       "code": 123
     *       "msg": "用户名或密码错误!"
     *   }
     */
    @PostMapping("/sel/doLogin")
    public ResultVO doLogin(String loginname, String pwd){
        //1. 请求参数校验
        if(StringUtils.isEmpty(loginname) || StringUtils.isEmpty(pwd)){
            // 参数不合法,直接返回
            log.info("【登录功能】 请求参数不合法！loginname = {}，pwd = {}",loginname,pwd);
            return R.error(HospitalEnum.PARAMETER_ERROR.getCode(),"用户名和密码均为必传项，岂能为空！");
        }

        //2. 获取subject
        Subject subject = SecurityUtils.getSubject();

        try {
            //3. 执行登录,返回正确信息
            subject.login(new UsernamePasswordToken(loginname,pwd));
            return R.msg("登陆成功！");
        } catch (UnknownAccountException | IncorrectCredentialsException e) {
            //4. 捕获异常,返回错误信息
            log.info("【登录功能】 用户名或密码错误! loginname = {}，pwd = {}",loginname,pwd);
            return R.error(HospitalEnum.USERNAME_PASSWORD_ERROR);
        }
    }

    /**
     * 退出登录
     * # 请求路径和方式
     * 	Request URL: http://localhost:8080/sel/logout
     * 	Request Method: GET
     * # 请求参数
     * 	无
     * # 响应数据
     *     SUCCESS:
     *     {
     *         "code": 0
     *         "msg": ""
     *     }
     *     FAIL:
     *     {
     *         "code": 123
     *         "msg": "退出登录失败!"
     *     }
     */
    @GetMapping("/sel/logout")
    public ResultVO logout(){
        //1. 获取subject并退出登录
        Subject subject = SecurityUtils.getSubject();
        subject.logout();

        //2. 响应
        return R.ok();
    }

    /**
     * 查询侧边栏菜单
     * # 请求路径&方式
     * 	Request URL: http://localhost:8080/sel/side
     * 	Request Method: GET
     * # 请求参数
     * 	无
     * # 响应数据
     * SUCCESS:
     * 数据的格式:
     * [
     *     {"一级菜单",children: [
     *         {"二级菜单"},
     *         {"二级菜单"},
     *         {"二级菜单"},
     *         ...
     *     ]},
     *     {"一级菜单"},
     *     {"一级菜单"},
     *     ...
     * ]
     */
    @GetMapping("/sel/side")
    public List<SideTreeVO> side(){
        //1. 通过Shiro的subject获取当前登录用户的信息
        Subject subject = SecurityUtils.getSubject();
        SysUser user = (SysUser) subject.getPrincipal();

        //2. 如果user为null，没有登录
        if(user == null){
            return null;
        }

        //3. 调用service查询当前用户的侧边栏信息
        List<SideTreeVO> result = sysUserService.findMenuByUserId(user.getUserId());

        //4. 返回
        return result;
    }


    /**
     * 查询用户信息
     * # 请求路径&方式
     *     Request URL: http://localhost:8080/user/selectAllUser
     *     Request Method: GET
     * # 请求参数
     * 	realname= String
     * 	loginname= String
     * 	address= String
     * 	phone= String
     * 	identity= String
     * 	page= Integer
     * 	limit= Integer
     * # 响应数据
     * SUCCESS：
     * {
     *     "code": 0,
     *     "msg": "",
     *     "count": 111,
     *     "data": [
     *         {"userid":1 ,"realname": "阿吧","loginname": "admin","identity": "123123123","phone": "18888888","address": "松花江下","position": "哑巴","sex": 0,"pwd": "****","available": 0}
     *     ]
     * }
     */
    @GetMapping("/user/selectAllUser")
    public ResultVO selectAllUser(SysUser sysUser, @RequestParam(defaultValue = "1")Integer page,@RequestParam(defaultValue = "10")Integer limit){
        //1. 调用service查询数据
        PageInfo<SysUser> pageInfo = sysUserService.findSysUserByConditionAndPage(sysUser, page, limit);

        //2. 响应数据
        return R.ok(pageInfo.getTotal(),pageInfo.getList());
    }


    /**
     *  查询全部角色信息
     * # path&method
     *     Request URL: http://localhost:8080/user/initUserRole
     *     Request Method: GET
     * # param
     * 	userid = Integer
     * # return
     * SUCCESS:
     * {
     *     "code": 0,
     *     "msg": "",
     *     "data": [
     *         {"roleid": 1,"rolename": "超级管理员","roledesc": "可以嘛嘛嘛"},
     *         ....
     *     ]
     * }
     */
    @GetMapping("/user/initUserRole")
    public ResultVO initUserRole(Integer userid){
        //1. 查询Service      LAY_CHECKED = true (查询全部角色)
        List<SysRoleDTO> list = sysUserService.findAllSysRole(userid);

        //2. 返回
        return R.ok(list);
    }


    /**
     * 分配角色
     * # path&method
     *     Request URL: http://localhost:8080/user/saveUserRole
     *     Request Method: POST
     * # param
     * 	    userid = integer
     * 	    ids = integer
     * 	    ids = integer
     * # return
     * SUCCESS:
     *        {"code": 0,"msg": "分配成功"}
     */
    @PostMapping("/user/saveUserRole")
    public ResultVO saveUserRole(Integer userid,Integer[] ids){
        //1. 校验参数
        if(userid == null){
            return R.error(HospitalEnum.PARAMETER_ERROR.getCode(),"用户id为必传项,岂能为空!");
        }

        //2. 调用service操作
        sysUserService.assignRoles(userid, ids);

        //3. 返回
        return R.msg("分配角色成功！");
    }
}
